package com.ff.xyh.consumer.online.user.config;

import com.ff.xyh.feign.config.MyRabbitConfigProperties;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.TimeUnit;


/**
 * @Auther FF
 * @Date 2023年 1月 10日
 * @Time 21:17
 */

/** 虽然在公用配置类已经定义过 但是还是得在本服务里面重新定义 以免混用 */

@Configuration
public class UserRabbitConfig {

    // 定义群聊交换机名
    public static final String EXCHANGE_DIRECT_USER = MyRabbitConfigProperties.EXCHANGE_DIRECT_USER;

    /**
     * 消息处理队列
     *    将消息处理后发送到用户消息队列
     */
    public static final String QUEUE_SERVER_MESSAGE = MyRabbitConfigProperties.QUEUE_SERVER_MESSAGE_2;
    public static final String ROUTING_KEY_MESSAGE = MyRabbitConfigProperties.ROUTING_KEY_MESSAGE_2;
    //    public static final String ROUTING_KEY_MESSAGE_2 = "UserServerRoutingKey1";

    /**
     * 用户消息队列
     *    将消息发到前端
     */
    public static final String QUEUE_SERVER_USER = MyRabbitConfigProperties.QUEUE_SERVER_USER_2;
    public static final String ROUTING_KEY_USER = MyRabbitConfigProperties.ROUTING_KEY_USER_2;
    //    public static final String ROUTING_KEY_USER_2 = "UserServerRoutingKey1";

    /**
     * 用户锁队列
     *    给登录等待线程解锁
     */
    public static final String QUEUE_SERVER_USER_LOCK = MyRabbitConfigProperties.QUEUE_SERVER_USER_LOCK_2;
    public static final String ROUTING_KEY_USER_LOCK = MyRabbitConfigProperties.ROUTING_KEY_USER_LOCK_2;




    /** 创建直接交换机并绑定对列的 方法一 : 通过bean注解声明并绑定 然后在消费者监听队列即可 */
    /** 1
     * 声明 用户 直接交换机
     * @return
     */
    @Bean
    public DirectExchange userDirectExchange () {
        return new DirectExchange(UserRabbitConfig.EXCHANGE_DIRECT_USER); }


    /** 创建用户队列， 用用户的routingKey绑定用户队列到交换机 */

    /** 2
     * 声明 本服务器的监听的用户队列
     * @return
     */
    @Bean
    public Queue serverUserQ1() { return new Queue(UserRabbitConfig.QUEUE_SERVER_USER); }
    @Bean
    public Queue serverMessageQ1() { return new Queue(UserRabbitConfig.QUEUE_SERVER_MESSAGE); }
    @Bean
    public Queue serverUserLockQ1() { return new Queue(UserRabbitConfig.QUEUE_SERVER_USER_LOCK); }

    /** 3
     * 根据路由绑定对列到交换机
     * @param serverUserQ1
     * @param userDirectExchange
     * @return
     */
    @Bean
    public Binding userQueueBinding(Queue serverUserQ1, DirectExchange userDirectExchange) {
        return BindingBuilder.bind(serverUserQ1).to(userDirectExchange).with(UserRabbitConfig.ROUTING_KEY_USER);
    }
    @Bean
    public Binding messageQueueBinding(Queue serverMessageQ1, DirectExchange userDirectExchange) {
        return BindingBuilder.bind(serverMessageQ1).to(userDirectExchange).with(UserRabbitConfig.ROUTING_KEY_MESSAGE);
    }
    @Bean
    public Binding userLockQueueBinding(Queue serverUserLockQ1, DirectExchange userDirectExchange) {
        return BindingBuilder.bind(serverUserLockQ1).to(userDirectExchange).with(UserRabbitConfig.ROUTING_KEY_USER_LOCK);
    }

//    /** 4
//     * 创建监听器 监听队列 到 监听类中声明
//     */
//    @RabbitListener(queues = QUEUE_SERVER_USER)
//    public void userOnlineQueueConsumer1(RoomMessage roomMessage) {
//        System.out.println("userOnlineQueueConsumer1 listen user.q1 received the message: {" + roomMessage + "}, when " + LocalTime.now());
//    }


    /** 方法二： 直接在监听器上声明队列交换机并绑定 */
//    @RabbitListener(bindings = @QueueBinding(
//            value = @org.springframework.amqp.rabbit.annotation.Queue(name = QUEUE_USER),
//            exchange = @org.springframework.amqp.rabbit.annotation.Exchange(name = EXCHANGE_DIRECT_USER, type = ExchangeTypes.DIRECT),
//            key = {ROUTING_KEY_USER_ONLINE, ROUTING_KEY_USER_ONLINE2}
//    ))






    /**
     * 添加自定义消息转换器 不需要声明 会自动注入
     * 原有消息转换器为序列化对象，性能差
     * 注意： 发送方与接收方需要使用相同的转换器
     * @return
     */
    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }


}